<template>
  <div class="human-library-page">
    <el-card class="page-card">
      <template #header>
        <div class="card-header">
          <span><el-icon><User /></el-icon> 数字人库</span>
          <div class="header-actions">
            <el-button @click="selectedFiles = []" v-if="selectedFiles.length > 0">
              取消选择 ({{ selectedFiles.length }})
            </el-button>
            <el-button type="danger" @click="batchDelete" v-if="selectedFiles.length > 0">
              批量删除
            </el-button>
            <el-button type="primary" @click="showUploadDialog = true">
              <el-icon><Upload /></el-icon>
              上传数字人
            </el-button>
          </div>
        </div>
      </template>

      <!-- 搜索栏 -->
      <div class="search-bar">
        <el-input
            v-model="searchKeyword"
            placeholder="搜索数字人名称"
            prefix-icon="Search"
            clearable
            @clear="handleSearch"
            @keyup.enter="handleSearch"
        />
        <el-button type="primary" @click="handleSearch">搜索</el-button>
      </div>

      <!-- 文件网格 -->
      <div v-loading="loading" class="file-grid">
        <div
            v-for="file in fileList"
            :key="file.file_id"
            class="file-item"
            :class="{ selected: isSelected(file.file_id) }"
            @click="toggleSelection(file)"
        >
          <div class="file-preview">
            <el-image
                :src="`${basePythonURL2}/api/preview-file/${file.file_id}`"
                fit="cover"
                lazy
            >
              <template #error>
                <div class="preview-error">
                  <el-icon><VideoPlay /></el-icon>
                </div>
              </template>
            </el-image>
            <div class="file-actions">
              <el-button
                  circle
                  size="small"
                  type="primary"
                  @click.stop="previewFile_f(file)"
              >
                <el-icon><View /></el-icon>
              </el-button>
              <el-button
                  circle
                  size="small"
                  type="danger"
                  @click.stop="deleteFile(file)"
              >
                <el-icon><Delete /></el-icon>
              </el-button>
            </div>
            <div v-if="isSelected(file.file_id)" class="selection-badge">
              <el-icon><Check /></el-icon>
            </div>
          </div>
          <div class="file-info">
            <h4 class="file-name" :title="file.original_name">
              {{ file.original_name }}
            </h4>
            <div class="file-meta">
              <el-tag size="small">{{ formatFileSize(file.file_size) }}</el-tag>
              <span class="upload-time">{{ formatDate(file.upload_time) }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 空状态 -->
      <el-empty v-if="!loading && fileList.length === 0" description="暂无数字人文件">
        <el-button type="primary" @click="showUploadDialog = true">上传数字人</el-button>
      </el-empty>

      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[12, 24, 48, 96]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
        />
      </div>
    </el-card>

    <!-- 上传对话框 -->
    <el-dialog
        v-model="showUploadDialog"
        title="上传数字人视频"
        width="700px"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        :before-close="handleUploadDialogClose"
    >
      <div v-if="!uploading">
        <el-upload
            ref="uploadRef"
            class="upload-demo"
            drag
            multiple
            :auto-upload="false"
            :file-list="uploadFileList"
            accept=".mov"
            @change="handleUploadChange"
            @remove="handleUploadRemove"
            :before-upload="beforeUpload"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">
              支持 MOV 格式，需要带透明通道<br>
              可以同时上传多个文件，支持大文件分片上传
            </div>
          </template>
        </el-upload>
      </div>

      <!-- 上传进度区域 -->
      <div v-if="uploading" class="upload-progress-area">
        <div class="upload-header">
          <h3>正在上传 {{ uploadProgress.current }} / {{ uploadProgress.total }}</h3>
          <el-button @click="cancelUpload" type="danger" size="small">取消上传</el-button>
        </div>

        <!-- 当前上传文件进度 -->
        <div class="current-upload" v-if="uploadProgress.fileName">
          <div class="file-info">
            <el-icon><VideoPlay /></el-icon>
            <span class="filename">{{ uploadProgress.fileName }}</span>
            <span class="filesize">({{ uploadProgress.fileSize }})</span>
          </div>

          <div class="progress-info">
            <div class="progress-text">
              <span>{{ uploadProgress.stage }}</span>
              <span>{{ uploadProgress.percent.toFixed(1) }}%</span>
            </div>
            <el-progress
                :percentage="uploadProgress.percent"
                :status="uploadProgress.percent === 100 ? 'success' : 'primary'"
                :stroke-width="8"
            />
          </div>

          <!-- 上传统计信息 -->
          <div class="upload-stats" v-if="uploadProgress.speed > 0">
            <span>速度: {{ formatSpeed(uploadProgress.speed) }}</span>
            <span v-if="uploadProgress.remainingTime > 0">
              剩余时间: {{ formatTime(uploadProgress.remainingTime) }}
            </span>
            <span>已上传: {{ formatFileSize(uploadProgress.uploaded) }}</span>
          </div>
        </div>

        <!-- 整体进度 -->
        <div class="overall-progress">
          <div class="progress-text">
            <span>总进度</span>
            <span>{{ overallProgress.toFixed(1) }}%</span>
          </div>
          <el-progress
              :percentage="overallProgress.toFixed(1)"
              :stroke-width="6"
          />
        </div>

        <!-- 上传队列 -->
        <div class="upload-queue" v-if="uploadFileList.length > 1">
          <div
              v-for="(file, index) in uploadFileList"
              :key="index"
              class="queue-item"
              :class="{
                'current': index === uploadProgress.current - 1,
                'completed': index < uploadProgress.current - 1,
                'pending': index > uploadProgress.current - 1
              }"
          >
            <el-icon>
              <Check v-if="index < uploadProgress.current - 1" />
              <Loading v-else-if="index === uploadProgress.current - 1" />
              <Clock v-else />
            </el-icon>
            <span>{{ file.name }}</span>
            <span class="file-size">{{ formatFileSize(file.size) }}</span>
          </div>
        </div>
      </div>

      <template #footer>
        <div v-if="!uploading">
          <el-button @click="showUploadDialog = false">取消</el-button>
          <el-button
              type="primary"
              @click="confirmUpload"
              :disabled="uploadFileList.length === 0"
          >
            确定上传 ({{ uploadFileList.length }} 个文件)
          </el-button>
        </div>
        <div v-else>
          <el-button @click="cancelUpload" type="danger">取消上传</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
        v-model="showPreviewDialog"
        :title="previewFile?.original_name"
        width="800px"
    >
      <div class="preview-content">
        <el-image
            :src="`${basePythonURL2}/api/preview-file/${previewFile?.file_id}`"
            fit="contain"
            style="width: 50%; height: 500px;"
        />
      </div>
      <div class="preview-info" v-if="previewFile">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="文件名">
            {{ previewFile.original_name }}
          </el-descriptions-item>
          <el-descriptions-item label="文件大小">
            {{ formatFileSize(previewFile.file_size) }}
          </el-descriptions-item>
          <el-descriptions-item label="上传时间" :span="2">
            {{ formatDate(previewFile.upload_time) }}
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import {ref, onMounted, computed, nextTick} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import api, { basePythonURL2 } from '../api'
import { Check, Clock, Delete, Loading, Upload, UploadFilled, User, VideoPlay, View } from "@element-plus/icons-vue"
import { smartUpload } from '@/utils/chunkedUploader'

// 响应式数据
const loading = ref(false)
const fileList = ref([])
const selectedFiles = ref([])
const currentPage = ref(1)
const pageSize = ref(12)
const total = ref(0)
const searchKeyword = ref('')
const showUploadDialog = ref(false)
const showPreviewDialog = ref(false)
const previewFile = ref(null)
const uploadFileList = ref([])
const uploading = ref(false)
const uploadRef = ref(null)

// 上传进度管理
const uploadProgress = ref({
  current: 0,        // 当前上传的文件索引（1-based）
  total: 0,          // 总文件数
  percent: 0,        // 当前文件上传进度
  stage: '',         // 当前阶段描述
  fileName: '',      // 当前文件名
  fileSize: '',      // 当前文件大小（格式化后）
  speed: 0,          // 上传速度（字节/秒）
  uploaded: 0,       // 已上传字节数
  remainingTime: 0,  // 剩余时间（秒）
  startTime: 0       // 开始时间
})

// 计算整体进度
const overallProgress = computed(() => {
  if (uploadProgress.value.total === 0) return 0
  const completedFiles = uploadProgress.value.current - 1
  const currentFileProgress = uploadProgress.value.percent / 100
  return ((completedFiles + currentFileProgress) / uploadProgress.value.total) * 100
})

// 基础方法（保持不变）
const loadFiles = async () => {
  loading.value = true
  try {
    const result = await api.getLibraryFiles('human', currentPage.value, pageSize.value)
    fileList.value = result.items || []
    total.value = result.total || 0
  } catch (error) {
    ElMessage.error('加载文件列表失败')
  } finally {
    loading.value = false
  }
}

const handleSearch = () => {
  currentPage.value = 1
  loadFiles()
}

const handlePageChange = (page) => {
  currentPage.value = page
  loadFiles()
}

const handleSizeChange = (size) => {
  pageSize.value = size
  currentPage.value = 1
  loadFiles()
}

const isSelected = (fileId) => {
  return selectedFiles.value.includes(fileId)
}

const toggleSelection = (file) => {
  const fileId = file.file_id
  const index = selectedFiles.value.indexOf(fileId)
  if (index > -1) {
    selectedFiles.value.splice(index, 1)
  } else {
    selectedFiles.value.push(fileId)
  }
}

const deleteFile = async (file) => {
  try {
    await ElMessageBox.confirm(
        `确定要删除文件 "${file.original_name}" 吗？`,
        '删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    await api.deleteLibraryFile(file.file_id)
    ElMessage.success('删除成功')
    loadFiles()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const batchDelete = async () => {
  if (selectedFiles.value.length === 0) {
    ElMessage.warning('请先选择要删除的文件')
    return
  }

  try {
    await ElMessageBox.confirm(
        `确定要删除选中的 ${selectedFiles.value.length} 个文件吗？`,
        '批量删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    await api.batchDeleteLibraryFiles(selectedFiles.value)
    ElMessage.success('批量删除成功')
    selectedFiles.value = []
    loadFiles()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('批量删除失败')
    }
  }
}

const previewFile_f = (file) => {
  previewFile.value = file
  showPreviewDialog.value = true
}

// 文件验证
const beforeUpload = (file) => {
  const maxSize = 10 * 1024 * 1024 * 1024 // 10GB
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过 10GB')
    return false
  }

  const allowedTypes = ['video/quicktime']
  if (!allowedTypes.includes(file.type)) {
    ElMessage.error('只支持 MOV/AVI 格式的视频文件')
    return false
  }

  return true
}

const handleUploadChange = (file, fileList) => {
  // 确保同步更新文件列表
  uploadFileList.value = [...fileList]
  console.log('上传列表更新:', uploadFileList.value.length, '个文件')
}

const handleUploadRemove = (file, fileList) => {
  // 当用户删除文件时，同步更新列表
  uploadFileList.value = [...fileList]
  console.log('文件已删除，剩余:', uploadFileList.value.length, '个文件')
}

// 修正后的上传方法
const confirmUpload = async () => {
  if (uploadFileList.value.length === 0) {
    ElMessage.warning('请选择要上传的文件')
    return
  }

  uploading.value = true

  // 初始化进度
  uploadProgress.value = {
    current: 0,
    total: uploadFileList.value.length,
    percent: 0,
    stage: '准备上传...',
    fileName: '',
    fileSize: '',
    speed: 0,
    uploaded: 0,
    remainingTime: 0,
    startTime: Date.now()
  }

  try {
    for (let i = 0; i < uploadFileList.value.length; i++) {
      const file = uploadFileList.value[i].raw

      // 更新当前上传文件信息
      uploadProgress.value.current = i + 1
      uploadProgress.value.fileName = file.name
      uploadProgress.value.fileSize = formatFileSize(file.size)
      uploadProgress.value.percent = 0
      uploadProgress.value.stage = '开始上传...'

      let lastTime = Date.now()
      let lastUploaded = 0
      const fileStartTime = Date.now()

      // 上传单个文件
      await smartUpload(file, 'human', (progress, stage) => {
        uploadProgress.value.percent = progress
        uploadProgress.value.stage = stage

        // 计算上传统计
        const now = Date.now()
        const uploaded = (progress / 100) * file.size
        uploadProgress.value.uploaded = uploaded

        // 计算上传速度（每0.5秒更新一次）
        const timeDiff = (now - lastTime) / 1000
        if (timeDiff > 0.5) {
          const uploadedDiff = uploaded - lastUploaded
          uploadProgress.value.speed = uploadedDiff / timeDiff

          // 计算剩余时间
          if (uploadProgress.value.speed > 0) {
            const remaining = file.size - uploaded
            uploadProgress.value.remainingTime = remaining / uploadProgress.value.speed
          }

          lastTime = now
          lastUploaded = uploaded
        }
      })
    }

    // ✅ 修正：先重置状态，再显示成功消息
    uploading.value = false

    // 延迟一小段时间确保状态更新完成
    await new Promise(resolve => setTimeout(resolve, 100))

    ElMessage.success(`成功上传 ${uploadFileList.value.length} 个文件`)

    // 自动关闭对话框并重置数据
    showUploadDialog.value = false
    resetUploadDialog()
    loadFiles()

  } catch (error) {
    uploading.value = false
    console.error('上传失败:', error)
    ElMessage.error(`上传失败: ${error.message}`)
  }
}

const cancelUpload = async () => {
  try {
    await ElMessageBox.confirm('确定要取消上传吗？', '取消确认', {
      confirmButtonText: '确定',
      cancelButtonText: '继续上传',
      type: 'warning'
    })

    uploading.value = false
    ElMessage.info('上传已取消')
    showUploadDialog.value = false
    await resetUploadDialog()
  } catch (error) {
    // 用户选择继续上传
  }
}

// 统一的重置方法
const resetUploadDialog = async () => {
  uploadFileList.value = []
  uploadProgress.value = {
    current: 0,
    total: 0,
    percent: 0,
    stage: '',
    fileName: '',
    fileSize: '',
    speed: 0,
    uploaded: 0,
    remainingTime: 0,
    startTime: 0
  }

  // 确保DOM更新后再清理Element Plus的文件列表
  await nextTick()

  if (uploadRef.value) {
    uploadRef.value.clearFiles()
    // 额外确保清理完成
    setTimeout(() => {
      if (uploadRef.value) {
        uploadRef.value.clearFiles()
      }
    }, 100)
  }

  console.log('上传对话框已重置')
}

const handleUploadDialogClose = async (done) => {
  // ✅ 修正：检查是否真正在上传中
  if (uploading.value && uploadProgress.value.current > 0 && uploadProgress.value.current <= uploadProgress.value.total) {
    ElMessage.warning('文件正在上传中，请等待完成或取消上传')
    return // 不调用 done()，阻止关闭
  }

  // 如果没有在上传或者上传已完成，重置并关闭
  await resetUploadDialog()
  if (done) done() // 允许关闭对话框
}

// 工具函数
const formatFileSize = (bytes) => {
  if (!bytes) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const formatSpeed = (bytesPerSecond) => {
  return formatFileSize(bytesPerSecond) + '/s'
}

const formatTime = (seconds) => {
  if (!seconds || seconds === Infinity) return '--'

  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = Math.floor(seconds % 60)

  if (hours > 0) {
    return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  } else {
    return `${minutes}:${secs.toString().padStart(2, '0')}`
  }
}

const formatDate = (dateStr) => {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN')
}

const isVideo = (filename) => {
  const ext = filename.split('.').pop().toLowerCase()
  return ['mov'].includes(ext)
}

// 生命周期
onMounted(() => {
  loadFiles()
})
</script>

<style lang="scss" scoped>
.human-library-page {
  max-width: 1400px;
  margin: 0 auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  span {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 20px;
    font-weight: 600;
  }

  .header-actions {
    display: flex;
    gap: 10px;
  }
}

.search-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;

  .el-input {
    flex: 1;
    max-width: 400px;
  }
}

.file-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
  min-height: 300px;
}

.file-item {
  position: relative;
  border: 2px solid transparent;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s ease;
  cursor: pointer;
  background: white;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);

    .file-actions {
      opacity: 1;
    }
  }

  &.selected {
    border-color: #409eff;
    box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.2);
  }
}

.file-preview {
  position: relative;
  width: 100%;
  height: 150px;
  background: #f5f7fa;

  .el-image {
    width: 100%;
    height: 100%;

    ::v-deep(.el-image__inner){
      width: auto;
      height: 100% !important;
      display: block !important;
      margin: auto !important;
    }
  }

  .preview-error {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: #c0c4cc;
    font-size: 48px;
  }

  .file-actions {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    gap: 10px;
    opacity: 0;
    transition: opacity 0.3s ease;
  }

  .selection-badge {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 28px;
    height: 28px;
    background: #409eff;
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.file-info {
  padding: 12px;

  .file-name {
    margin: 0 0 8px 0;
    font-size: 14px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .file-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .upload-time {
      font-size: 12px;
      color: #909399;
    }
  }
}

.pagination-wrapper {
  margin-top: 30px;
  display: flex;
  justify-content: center;
}

.upload-demo {
  ::v-deep(.el-upload-dragger) {
    width: 100%;
    height: 200px;
  }
}

.upload-progress-area {
  min-height: 300px;

  .upload-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 1px solid #ebeef5;

    h3 {
      margin: 0;
      font-size: 18px;
      color: #303133;
    }
  }

  .current-upload {
    margin-bottom: 30px;
    padding: 20px;
    background: #f8f9fa;
    border-radius: 8px;

    .file-info {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 15px;

      .filename {
        font-weight: 500;
        color: #303133;
      }

      .filesize {
        color: #909399;
        font-size: 14px;
      }
    }

    .progress-info {
      margin-bottom: 10px;

      .progress-text {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
        font-size: 14px;
        color: #606266;
      }
    }

    .upload-stats {
      display: flex;
      gap: 20px;
      font-size: 12px;
      color: #909399;
    }
  }

  .overall-progress {
    margin-bottom: 20px;

    .progress-text {
      display: flex;
      justify-content: space-between;
      margin-bottom: 8px;
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }
  }

  .upload-queue {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid #ebeef5;
    border-radius: 6px;

    .queue-item {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 15px;
      border-bottom: 1px solid #f5f7fa;

      &:last-child {
        border-bottom: none;
      }

      &.current {
        background: #e1f3d8;
        color: #67c23a;
      }

      &.completed {
        color: #67c23a;
      }

      &.pending {
        color: #909399;
      }

      .file-size {
        margin-left: auto;
        font-size: 12px;
        color: #c0c4cc;
      }
    }
  }
}

.preview-content {
  text-align: center;
  margin-bottom: 20px;
}

.preview-info {
  margin-top: 20px;
}
</style>